package com.everwin.web.controller.common;

import com.everwin.common.config.ServerConfig;
import com.everwin.common.core.domain.AjaxResult;
import com.everwin.web.controller.common.service.FileService;
import com.everwin.web.domain.DownloadFileDesc;
import com.everwin.web.domain.FileDetail;
import com.everwin.web.domain.UploadResultDesc;
import com.everwin.web.utils.DownloadUtil;
import com.everwin.web.utils.FileStore;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;

@Controller
public class FileController {
    private static final Logger log = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private FileStore fileStore;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private FileService fileService;

    @Value("${upload-max-size:10485760}")
    private int maxSize;

    @Value("${upload-file-max-size:5242880}")
    private int fileMaxSize;

    @PostMapping("/file/upload")
    @ResponseBody
    public AjaxResult upload(MultipartFile file) throws Exception {
        UploadResultDesc resultDesc = new UploadResultDesc();
        if (file.isEmpty()){
            return AjaxResult.error("文件为空！");
        }
        try{
            InputStream fileStream=file.getInputStream();
            String fileOriginName=file.getOriginalFilename();
            String encodedStr = URLEncoder.encode(URLDecoder.decode(fileOriginName,"UTF-8"),"UTF-8");
            String decodeStr = URLDecoder.decode(encodedStr,"UTF-8");
            String extension=getExtension(decodeStr);
            resultDesc.setOriginFileName(decodeStr);
            resultDesc.setExtension(extension);
            saveFile(fileStream,resultDesc);
            if(!resultDesc.isSuccess()) {
                return AjaxResult.error("系统异常，存储图片失败！",resultDesc);
            }
        }catch (Exception e) {
            return AjaxResult.error(e.getMessage(),resultDesc);
        }

        return AjaxResult.success("文件上传成功！",resultDesc);
    }

    private String getExtension(String decodeStr) {
        String extension = decodeStr.substring(decodeStr.lastIndexOf(".") + 1);
        return extension;
    }

    @GetMapping("/file/download")
    @ResponseBody
    public ResponseEntity download(@RequestParam("id") String id) throws Exception {
        DownloadFileDesc downloadFileDesc = DownloadUtil.getDownloadFileDesc(id);
        String fileHash = downloadFileDesc.getHash();
        File file = fileStore.get(fileHash);
        if(file == null) return ResponseEntity.status(500).body("file not exits");
        String fullFileName = getFileName(fileHash);
        try{
            HttpHeaders headers = new HttpHeaders();
            // 解决中文乱码
            // 以下载方式打开文件
            if(downloadFileDesc.isDownload()) {
                String downloadfile =  new String(fullFileName.getBytes("UTF-8"),"iso-8859-1");
                headers.setContentDispositionFormData("attachment", downloadfile);
            }
            // 二进制流
            headers.setContentType(downloadFileDesc.getMediaType());
            return new ResponseEntity<>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
        }catch (Exception e){
            throw new RuntimeException("下载文件出错");
        }
    }

    public void saveFile(InputStream fileStream,UploadResultDesc resultDesc) throws IOException, NoSuchAlgorithmException {
        String originalFileName = resultDesc.getOriginFileName();
        String hash = saveFile(fileStream,originalFileName);
        resultDesc.setFileHash(hash);
    }

    public String saveFile(InputStream fileStream,String originalFileName) throws IOException, NoSuchAlgorithmException {
        FileDetail fileDetail = new FileDetail();
        log.info("原始文件名:{}",originalFileName);
        int pointIndex = originalFileName.lastIndexOf(".");
        String fileName = pointIndex<0?originalFileName:originalFileName.substring(0,pointIndex);
        String fileSuffix = pointIndex<0?"":originalFileName.substring(pointIndex+1);
        fileDetail.setFileName(fileName);
        fileDetail.setFileSuffix(fileSuffix);
        File tmp=File.createTempFile(System.currentTimeMillis()+"","linkfin");
        FileUtils.copyInputStreamToFile(fileStream,tmp);
        String hash = fileStore.put(tmp);
        tmp.delete();
        fileDetail.setFileHash(hash);
        fileService.saveFileDetail(fileDetail);
        return hash;
    }

    private String getFileName(String hash){
        FileDetail fileDetail = fileService.getFileDetail(hash);
        if(fileDetail ==null) return hash;
        String fileName = fileDetail.getFileName();
        String fileSuffix = fileDetail.getFileSuffix();
        String fullFileName = fileName + "." + fileSuffix;
        return fullFileName;
    }
}
